<template>
  <div>
    <a-card class="card" title="物料BOM">
      <a-form :form="form">
        <a-row class="form-row" :gutter="16">
          <a-form-item v-show="false"><a-input v-decorator="['id']" /></a-form-item>
          <a-form-item v-show="false"><a-input v-decorator="['bomCode']" /></a-form-item>
          <a-form-item v-show="false"><a-input v-decorator="['materialCode']" /></a-form-item>
          <a-col :lg="6" :md="12" :sm="24">
            <a-form-item
              label="物料编码">
              <a-input read-only style="width: 100%" @click="handleMaterialOpen()" v-decorator="['materialName',{rules: [{ required: true, message: '请选择物料编码'}]}]"/>
            </a-form-item>
          </a-col>
          <a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
            <a-form-item
              label="BOM版本">
              <a-input style="width: 100%" v-decorator="['bomVersion',{rules: [{ required: true, message: '请填写BOM版本'}]}]"/>
            </a-form-item>
          </a-col>
          <a-col :xl="{span: 7, offset: 1}" :lg="{span: 8}" :md="{span: 12}" :sm="24">
            <a-form-item
              label="是否启用"
            >
              <a-select style="width: 100%" placeholder="请选择是否启用" v-decorator="['isEnable', {rules: [{ required: true, message: '请选择是否启用！' }], initialValue: '1'}]">
                <a-select-option v-for="(item,index) in isEnableData" :key="index" :value="item.code">{{ item.name }}</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
        </a-row>
        <a-row class="form-row" :gutter="16">
          <a-col>
            <a-form-item
              label="备注">
              <a-textarea placeholder="请输入备注" v-decorator="['remark']"/>
            </a-form-item>
          </a-col>
        </a-row>
        <select-material ref="selectMaterial" :selected-rows-data="selectedMaterialRowsData" :selected-row-keys-data="selectedMatetialRowKeysData" :select-type="selectType" @sure="handleMaterialSure" />
      </a-form>
    </a-card>
    <a-card class="card" title="BOM明细">
      <a-table
        :columns="itemColumns"
        :dataSource="itemData"
        bordered
        size="small"
        :pagination="false"
        :scroll="{x: 1000}"
      >
        <template v-for="col in customRenderList" v-slot:[col]="text, record">
          <div :key="col">
            <a-form-item :validate-status="getFiledStatus(record.key, col)" style="margin-bottom: 0px">
              <a-input
                :read-only="readonlyArr.includes(col)"
                placeholder="请输入"
                v-if="record.editable && inputScopedSlots.includes(col)"
                :value="text"
                @change="e => handleChangeItem(e.target.value, record.key, col)"
              />
              <a-input
                :read-only="readonlyArr.includes(col)"
                placeholder="请输入"
                v-else-if="record.editable && col==='itemMaterialCode'"
                :value="text"
                @click="handleItemMaterialOpen(record)"
                @change="e => handleChangeItem(e.target.value, record.key, col)"
              />
              <a-select
                :value="record.itemBomVersion"
                :read-only="readonlyArr.includes(col)"
                placeholder="请选择"
                style="width: 90%"
                v-else-if="record.editable && col==='itemBomVersion'"
                @change="e => handleChangeItem(e, record.key, col)"
              >
                <a-select-option v-for="(item,index) in record.bomVersionData" :key="index" :value="item">{{ item }}</a-select-option>
              </a-select>
              <a-select
                :value="record.isMain"
                :read-only="readonlyArr.includes(col)"
                placeholder="请选择"
                style="width: 90%"
                v-else-if="record.editable && col==='isMain'"
                @change="e => handleChangeItem(e, record.key, col)"
              >
                <a-select-option v-for="(item,index) in isEnableData" :key="index" :value="item.code">{{ item.name }}</a-select-option>
              </a-select>
              <span v-else>{{ text }}</span>
            </a-form-item>
          </div>
        </template>
        <template slot="operation" slot-scope="text, record">
          <span>
            <a-popconfirm title="是否要删除此行？" @confirm="remove(record.key)">
              <a>删除</a>
            </a-popconfirm>
          </span>
        </template>
      </a-table>
      <a-button style="width: 100%; margin-top: 16px; margin-bottom: 8px" type="dashed" icon="plus" @click="newItem">新增BOM明细</a-button>
      <select-material ref="selectItemMaterial" :selected-rows-data="selectedMaterialRowsData" :selected-row-keys-data="selectedMatetialRowKeysData" :select-type="selectType" @sure="handleItemMaterialSure" />
    </a-card>
    <!-- fixed footer toolbar -->
    <footer-tool-bar>
      <a-button class="subButton" @click="handleCancel">取消</a-button>
      <a-button type="primary" @click="handleSubmit" :loading="loading">提交</a-button>
    </footer-tool-bar>
  </div>
</template>

<script>
import FooterToolBar from '@/components/FooterToolbar'
import { materialBomEdit, materialBomDetail, listVersion } from '@/api/modular/main/base/material/materialBomManage'
import selectMaterial from '@/components/bizComponents/selectMaterial.vue'
import BigNumber from 'bignumber.js'
import { validateNum, validateNum16 } from '@/utils/validate'
export default {
  components: {
    BigNumber,
    FooterToolBar,
    selectMaterial
  },
  data () {
    return {
      isMain: '1',
      bomCode: '',
      loading: false,
      isEnableData: [],
      itemData: [],
      // 每一列的插槽名 - 表格行内编辑用
      customRenderList: ['itemMaterialCode', 'itemBomVersion', 'materialName', 'materialModel', 'qty', 'unit', 'scrapRate', 'isMain'],
      // 用来匹配插槽中显示input框
      inputScopedSlots: ['qty', 'scrapRate'],
      // 对于某些自动赋值的input框设为 只读
      readonlyArr: ['materialName', 'materialModel', 'unit'],
      // 需要验证的字段
      needValidItemFields: ['itemMaterialCode', 'qty', 'isMain', 'itemBomVersion'],
      form: this.$form.createForm(this),
      selectedMaterialRowsData: [],
      selectedMatetialRowKeysData: [],
      selectType: 'checkbox',
      selectedItemKey: '',
      itemColumns: [
        {
          title: '物料编码',
          dataIndex: 'itemMaterialCode',
          align: 'center',
          width: 200,
          scopedSlots: { customRender: 'itemMaterialCode' }
        },
        {
          title: '物料名称',
          dataIndex: 'materialName',
          align: 'center',
          width: 200,
          scopedSlots: { customRender: 'materialName' }
        },
        {
          title: '物料型号',
          dataIndex: 'materialModel',
          align: 'center',
          width: 300,
          scopedSlots: { customRender: 'materialModel' }
        },
        {
          title: 'BOM版本',
          dataIndex: 'itemBomVersion',
          align: 'center',
          width: 120,
          scopedSlots: { customRender: 'itemBomVersion' }
        },
        {
          title: '数量',
          dataIndex: 'qty',
          align: 'center',
          width: 120,
          scopedSlots: { customRender: 'qty' }
        },
        {
          title: '单位',
          dataIndex: 'unit',
          align: 'center',
          width: 80,
          scopedSlots: { customRender: 'unit' }
        },
        {
          title: '损耗率',
          dataIndex: 'scrapRate',
          align: 'center',
          width: 120,
          scopedSlots: { customRender: 'scrapRate' }
        },
        {
          title: '是否核心组件',
          dataIndex: 'isMain',
          align: 'center',
          width: 150,
          scopedSlots: { customRender: 'isMain' }
        },
        {
          title: '操作',
          dataIndex: 'action',
          align: 'center',
          width: 80,
          scopedSlots: { customRender: 'operation' }
        }
      ]
    }
  },
  created () {
    this.newItem()
    const isEnableOption = this.$options
    this.isEnableData = isEnableOption.filters['dictData']('whether')
  },
  activated () {
    const oldCode = this.bomCode
    this.bomCode = this.$route.query.bomCode
    if (oldCode !== this.bomCode) {
      materialBomDetail(this.bomCode).then((res) => {
        if (res.success) {
          this.edit(res.data)
        } else {
          this.$message.error('数据加载失败:' + res.message)
        }
      })
    }
  },
  deactivated () {
  },
  methods: {
    edit (record) {
      this.form.setFieldsValue(
        {
          id: this.$praseStrEmpty(record.id),
          bomCode: this.$praseStrEmpty(record.bomCode),
          bomVersion: this.$praseStrEmpty(record.bomVersion),
          materialCode: this.$praseStrEmpty(record.materialCode),
          materialName: this.$praseStrEmpty(record.materialName),
          isEnable: record.isEnable + '',
          remark: this.$praseStrEmpty(record.remark)
        }
      )
      this.itemData = []
      let idx = 0
      for (const item of record.itemList) {
        this.itemData.push({
          key: (++idx).toString(),
          itemMaterialCode: item.itemMaterialCode,
          itemBomVersion: item.itemBomVersion,
          materialName: item.materialName,
          materialModel: item.materialModel,
          qty: item.qty,
          unit: item.unit,
          scrapRate: item.scrapRate,
          isMain: item.isMain + '',
          bomVersionData: item.bomVersionData,
          selectedRowKeysData: [ item.materialCode ],
          editable: true,
          isNew: false,
          validateStatus: []
        })
      }
    },
    handleMaterialOpen () {
      this.selectType = 'radio'
      // 设置已选明细物料信息
      this.selectedMaterialRowsData = []
      this.selectedMatetialRowKeysData = []
      const materialCode = this.form.getFieldValue('materialCode')
      if (materialCode !== '') {
        this.selectedMatetialRowKeysData.push(materialCode)
      }
      this.$refs.selectMaterial.add()
    },
    handleItemMaterialOpen (record) {
      this.selectedItemKey = record.key
      this.selectType = 'radio'
      // 设置已选明细物料信息
      this.selectedMaterialRowsData = []
      this.selectedMatetialRowKeysData = []
      this.selectedMatetialRowKeysData.push(record['itemMaterialCode'])
      this.$refs.selectItemMaterial.add()
    },
    handleMaterialSure (selectedMaterialRowsData, selectedMatetialRowKeysData) {
      const newMaterialCode = selectedMaterialRowsData[0].code
      const newMaterialName = selectedMaterialRowsData[0].name
      this.form.setFieldsValue({ materialCode: newMaterialCode, materialName: newMaterialName })
    },
    handleItemMaterialSure (selectedMaterialRowsData, selectedMatetialRowKeysData) {
      const newData = [...this.itemData]
      const checkMaterial = newData.find(item => selectedMaterialRowsData[0].code === item.materialCode)
      if (checkMaterial && checkMaterial.key !== this.selectedItemKey) {
        this.$message.error('物料[' + selectedMaterialRowsData[0].code + ']已存在，请选择其他物料')
      } else {
        const target = newData.find(item => this.selectedItemKey === item.key)
        if (target) {
          target['itemMaterialCode'] = selectedMaterialRowsData[0].code
          target['materialName'] = selectedMaterialRowsData[0].name
          target['materialModel'] = selectedMaterialRowsData[0].model
          target['unit'] = selectedMaterialRowsData[0].unit
          target['selectedRowKeysData'] = selectedMatetialRowKeysData
          this.itemData = newData
          this.validateItemField(this.selectedItemKey, 'itemMaterialCode', target['itemMaterialCode'])
          listVersion(selectedMaterialRowsData[0].code).then((res) => {
            target['bomVersionData'] = res.data
          })
        }
      }
    },
    newItem () {
      const length = this.itemData.length
      this.itemData.push({
        key: length === 0 ? '1' : (parseInt(this.itemData[length - 1].key) + 1).toString(),
        itemMaterialCode: '',
        materialName: '',
        materialModel: '',
        itemBomVersion: '',
        qty: '',
        unit: '',
        scrapRate: '0.00',
        isMain: '0',
        bomVersionData: [],
        selectedRowKeysData: [],
        editable: true,
        isNew: true,
        validateStatus: []
      })
    },
    remove (key) {
      const newData = this.itemData.filter(item => item.key !== key)
      this.itemData = newData
    },
    getRowByKey (key, newData) {
      const data = this.itemData
      return (newData || data).find(item => item.key === key)
    },
    handleChangeItem (value, key, colName) {
      const newData = [...this.itemData]
      const target = newData.find(item => key === item.key)
      if (target) {
        target[colName] = value
        this.itemData = newData
      }
      this.validateItemField(key, colName, value)
    },
    getFiledStatus (key, col) {
      const target = this.itemData.find(item => key === item.key)
      if (target) {
        const statusObj = target['validateStatus'].find(item => col === item.col)
        if (statusObj) {
          return statusObj['status']
        }
      }
      return 'success'
    },
    setFiledStatus (key, col, error) {
      const status = error ? 'error' : 'success'
      const newData = [...this.itemData]
      const target = newData.find(item => key === item.key)
      if (target) {
        const statusObj = target['validateStatus'].find(item => col === item.col)
        if (statusObj) {
          statusObj['col'] = col
          statusObj['status'] = status
        } else {
          target['validateStatus'].push({
            col: col,
            validateStatus: status
          })
        }
        this.itemData = newData
      }
    },
    validateItemField (key, col, value) {
      if (col === 'itemMaterialCode') {
        this.setFiledStatus(key, col, false)
        if (value === null || value === '') {
            this.setFiledStatus(key, col, true)
            return false
        }
      }
      if (col === 'scrapRate') {
        this.setFiledStatus(key, col, false)
        if (value === null || value === '' || !validateNum16(value)) {
            this.setFiledStatus(key, col, true)
            return false
        }
      }
      if (col === 'qty') {
        this.setFiledStatus(key, col, false)
        if (value === null || value === '' || !(validateNum(value).result)) {
            this.setFiledStatus(key, col, true)
            return false
        }
      }
      if (col === 'itemBomVersion') {
        this.setFiledStatus(key, col, false)
        const target = this.itemData.find(item => key === item.key)
        if (target && target['bomVersionData'] !== null && target['bomVersionData'].length > 0) {
          if (!value || value === null || value === '') {
            this.setFiledStatus(key, col, true)
            return false
          }
        }
      }
      return true
    },
    filterEmptyItem () {
      const emptyKeys = []
      for (var data of this.itemData) {
        var key = data.key
        let allEmpty = true
        for (var field of this.needValidItemFields) {
          if (data[field] !== null && data[field] !== '') {
            allEmpty = false
          }
        }
        if (allEmpty) {
          emptyKeys.push(key)
        }
      }
      // 全空则直接删除该条数据
      if (emptyKeys.length > 0) {
        if (emptyKeys.length === this.itemData.length) {
          emptyKeys.splice(0, 1)
        }
        this.itemData = this.itemData.filter(item => !emptyKeys.includes(item.key))
      }
    },
    validateAllItemFields () {
      this.filterEmptyItem()
      if (this.itemData === null || this.itemData.length === 0) {
        this.$message.error('BOM明细不能为空！')
        return false
      }
      var flag = true
      for (var data of this.itemData) {
        var key = data.key
        for (var field of this.needValidItemFields) {
          if (flag && !this.validateItemField(key, field, data[field])) {
            flag = false
          }
        }
      }
      return flag
    },
    /**
     * 提交表单
     */
    handleSubmit () {
      var flag = this.validateAllItemFields()
      const { form: { validateFields } } = this
      this.loading = true
      validateFields((errors, values) => {
        if (!errors) {
          for (const key in values) {
            if (typeof (values[key]) === 'object') {
              values[key] = JSON.stringify(values[key])
            }
          }
          if (!flag) {
            this.loading = false
            return
          }
          values['itemList'] = this.itemData
          // console.log(values)
          materialBomEdit(values).then((res) => {
            if (res.success) {
              this.$message.success('保存成功')
              this.loading = false
              this.$emit('ok', values)
              this.handleCancel()
            } else {
              this.$message.error('保存失败:' + res.message)
            }
          }).finally((res) => {
            this.loading = false
          })
        } else {
           this.loading = false
        }
      })
    },
    handleCancel () {
      this.bomCode = ''
      this.form.resetFields()
      this.itemData = []
      this.newItem()
      this.$multiTab.closeAndOpen('/materialBom')
    }
  }
}
</script>

<style lang="less" scoped>
  .card{
    margin-bottom: 10px;
  }
  button {
    margin-right: 8px;
  }
</style>
